﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.WowAddonStudio.FrameXml.Services;

namespace Microsoft.WowAddonStudio.FrameXml.Components.Editors
{
	public class FolderPickerElement : PickerElement
	{
		private readonly List<PickerElement> elements;

		/// <summary>
		/// Initializes a new instance of the <see cref="FolderPickerElement"/> class.
		/// </summary>
		/// <param name="name">The name.</param>
		public FolderPickerElement(string name)
			: base(name)
		{
			elements = new List<PickerElement>();
		}

		/// <summary>
		/// Gets a value indicating whether this instance has child.
		/// </summary>
		/// <value><c>true</c> if this instance has child; otherwise, <c>false</c>.</value>
		public override bool HasChild
		{
			get { return elements.Count > 0; }
		}

        /// <summary>
        /// Adds the specified name.
        /// </summary>
        /// <param name="resourceFile">The resource file.</param>
		public override void Add(ResourceFile resourceFile)
		{
            string prefix = GetPrefix(resourceFile.Name);

			if (prefix != DisplayName)
				throw new ApplicationException("Cannot add child element to this node.");

            string postfix = GetPostfix(resourceFile.Name, prefix);

			if (string.IsNullOrEmpty(Path.GetDirectoryName(postfix)))
			{
                elements.Add(new LeafPickerElement(postfix, resourceFile.Path) { ResourceFileType = resourceFile.ResourceFileType });
			}
			else
			{
				FolderPickerElement childFolder = GetChildFolderElement(postfix);
			    childFolder.ResourceFileType = resourceFile.ResourceFileType;
			    resourceFile.Name = postfix;
				childFolder.Add(resourceFile);
			}
		}

		/// <summary>
		/// Gets the children.
		/// </summary>
		/// <returns></returns>
		public override IEnumerable<PickerElement> GetChildren
		{
			get { return elements; }
		}

		/// <summary>
		/// Gets the child folder element.
		/// </summary>
		/// <param name="postfix">The postfix.</param>
		/// <returns></returns>
		private FolderPickerElement GetChildFolderElement(string postfix)
		{
			string childName = GetPrefix(postfix);
			var childFolder = elements.FirstOrDefault(element => element is FolderPickerElement &&
			                                                     element.DisplayName == childName);

			if (childFolder == null)
			{
				childFolder = new FolderPickerElement(childName);
				elements.Add(childFolder);
			}

			return childFolder as FolderPickerElement;
		}

		/// <summary>
		/// Gets the prefix.
		/// </summary>
		/// <param name="elementName">Name of the element.</param>
		/// <returns></returns>
		private static string GetPrefix(string elementName)
		{
			string prefix = elementName;

		    if (elementName.IndexOf(Path.DirectorySeparatorChar) == 0)
		        prefix = elementName.Substring(1);

		    if (prefix.IndexOf(Path.DirectorySeparatorChar) > -1)
		        prefix = prefix.Substring(0, prefix.IndexOf(Path.DirectorySeparatorChar));

		    return prefix.Trim();
		}

		/// <summary>
		/// Gets the postfix.
		/// </summary>
		/// <param name="elementName">Name of the element.</param>
		/// <param name="prefix">The prefix.</param>
		/// <returns></returns>
		private static string GetPostfix(string elementName, string prefix)
		{
			string postfix = elementName;

		    if (elementName.IndexOf(Path.DirectorySeparatorChar) == 0)
		        postfix = elementName.Substring(1);

		    postfix = postfix.Substring(prefix.Length);
			if (postfix.IndexOf(Path.DirectorySeparatorChar) == 0)
				postfix = postfix.Substring(1);

			return postfix.Trim();
		}
	}
}